using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using PoliceBase;

namespace MapControl
{
    public partial class MapControl : UserControl
    {
        #region DataFields
        private string _conn = "";
        private int _maxX, _maxY;
        private Path[] _paths;
        private Node[] _cars;
        private Node[] _high;
        private int _carID = -1;
        private DBBasic _dd = null;
        private int offset = 10;
        private bool displayAllCars = true;

        private Brush backBrush = Brushes.Black;
        private Brush carBrush = Brushes.Green;
        private Brush incidentBrush = Brushes.Blue;
        private Brush shortestPathBrush = Brushes.Red;
        #endregion

        #region Properties
        public string ConnectionString
        {
            get { return _conn; }
            set 
            { 
                _conn = value;
                _dd = new DBBasic(_conn);
                _maxX = _dd.GetMaxX();
                _maxY = _dd.GetMaxY();
                _paths = _dd.LaodAllPaths();
            }
        }
        public bool DisplayAllCars
        {
            get { return displayAllCars; }
            set { displayAllCars = value; }
        }
        public int CarID
        {
            get { return _carID; }
            set { _carID = value; }
        }
        public Node[] High
        {
            get { return _high; }
            set { _high = value; }
        }
        #endregion

        #region Constructors
        public MapControl()
        {
            InitializeComponent();
        }
        #endregion

        #region PublicMethods
        #endregion

        #region PrivateMethods
        private void drawCircle(Brush b, Graphics g, Node n)
        {
            if (n == null) return;
            int wi = 5;
            g.FillEllipse(b, normX(n.X) - wi + offset, normY(n.Y) - wi + offset, 2 * wi, 2 * wi);
        }
        private void drawLine(Brush b, Graphics g, Path n)
        {
            if (n == null) return;
            drawLine(b, g, n.StatingNode, n.EndingNode);
        }
        private void drawLine(Brush b, Graphics g, Node n1, Node n2)
        {
            if ((n1 == null) || (n2 == null)) return;
            g.DrawLine(new Pen(b, 3), new Point((int)normX(n1.X) + offset, (int)normY(n1.Y) + offset), new Point((int)normX(n2.X) + offset, (int)normY(n2.Y) + offset));
        }
        private float normX(double d)
        {
            return (float)((d / _maxX) * (Width - 2 * offset));
        }
        private float normY(double d)
        {
            return (float)((d / _maxY) * (Height - 2 * offset));
        }
        #endregion

        #region EventHandlers
        private void backPanel_Paint(object sender, PaintEventArgs e)
        {
            if (_dd != null)
            {
                Graphics g = backPanel.CreateGraphics();
                if (_paths != null)
                    for (int i = 1; i < _paths.Length; i++)
                    {
                        drawCircle(backBrush, g, _paths[i].StatingNode);
                        drawCircle(backBrush, g, _paths[i].EndingNode);
                        drawLine(backBrush, g, _paths[i].StatingNode, _paths[i].EndingNode);
                    }

                if (displayAllCars)
                {
                    _cars = _dd.LoadCarsPositions();
                    if (_cars != null)
                        for (int i = 0; i < _cars.Length; i++)
                            if (_cars[i] != null) drawCircle(carBrush, g, _cars[i]); 
                }

                if (_carID != -1)
                {
                    Node carPos = _dd.LoadCarPosition(_carID);
                    if (_high != null)
                    {
                        drawLine(shortestPathBrush, g, carPos, _high[0]);
                        for (int i = 0; i < _high.Length - 1; i++)
                        {
                            drawCircle(shortestPathBrush, g, _high[i]);
                            drawLine(shortestPathBrush, g, _high[i], _high[i + 1]);
                        }
                        drawCircle(incidentBrush, g, _high[_high.Length - 1]);
                    }
                    drawCircle(carBrush, g, carPos);
                }
            }
        }
        #endregion
    }
}